﻿using Microsoft.Data.Sqlite;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.IO;
using WpfApp.Models;
using WpfApp.Services;

namespace WpfApp.Tests
{
    [TestClass]
    public class DataServiceTests
    {
        private DataService _dataService;
        private static readonly string BaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
        private static readonly string DbFilePath = Path.GetFullPath(Path.Combine(BaseDirectory, "..", "..", "..","..","WpfApp", "Data", "register.db"));
        private static readonly string ConnectionString = $"Data Source={DbFilePath};Mode=ReadWriteCreate;";

        [TestInitialize]
        public void SetUp()
        {
            _dataService = new DataService();
        }

        [TestMethod]
        public void DatabaseConnectionTest()
        {
            bool canConnect = false;
            using (var connection = new SqliteConnection(ConnectionString))
            {
                try
                {
                    connection.Open();
                    canConnect = true;

                    using (var command = new SqliteCommand("SELECT 1", connection))
                    {
                        command.ExecuteScalar();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Exception during connection: {ex.Message}");
                    canConnect = false;
                }
            }

            Assert.IsTrue(canConnect, "Database connection should be established successfully.");
        }

        [TestMethod]
        public void Login_ShouldReturnTrue_WhenCredentialsAreCorrect()
        {
            string username = "testUser";
            string password = "testPass";
            _dataService.Register(username, password);

            bool result = _dataService.Login(username, password);

            Assert.IsTrue(result, "Login should succeed with correct credentials.");
        }

        [TestMethod]
        public void Register_ShouldReturnFalse_WhenUsernameAlreadyExists()
        {
            // Arrange
            string username = "testUser";
            string password = "testPass";
            _dataService.Register(username, password);

            // Act
            bool result = _dataService.Register(username, password);

            // Assert
            Assert.IsFalse(result, "Register should fail if username already exists.");
        }

        [TestMethod]
        public void WordBook_ShouldReturnEmptyList_WhenNoWordBooksExist()
        {
            // Arrange
            string username = "testUser";
            string password = "testPass";
            _dataService.Register(username, password);

            // Act
            List<Dictionary> wordBooks = _dataService.WordBook(username);

            // Assert
            Assert.IsNotNull(wordBooks, "WordBooks should not be null.");
           // Assert.AreEqual(2, wordBooks.Count, "WordBooks should contain default word books.");
        }

        [TestMethod]
        public void AddWord_ShouldReturnTrue_WhenWordIsAddedSuccessfully()
        {
            // Arrange
            string username = "testUser";
            string password = "testPass";
            _dataService.Register(username, password);
            string wordBookTitle = "我的生词本";
            Word newWord = new Word
            {
                Name = "example",
                Score = 0,
                Meaning = new Dictionary<string, string> { { "English", "example meaning" } }
            };

            // Act
            bool result = _dataService.AddWord(username, wordBookTitle, newWord);

            // Assert
            Assert.IsTrue(result, "AddWord should succeed if word does not already exist.");
        }

        [TestMethod]
        public void ChangeWord_ShouldReturnTrue_WhenWordScoreIsUpdated()
        {
            // Arrange
            string username = "testUser";
            string password = "testPass";
            _dataService.Register(username, password);
            string wordBookTitle = "我的生词本";
            Word newWord = new Word
            {
                Name = "example",
                Score = 0,
                Meaning = new Dictionary<string, string> { { "English", "example meaning" } }
            };
            _dataService.AddWord(username, wordBookTitle, newWord);
            newWord.Score = 3;

            // Act
            bool result = _dataService.ChangeWord(username, wordBookTitle, newWord);

            // Assert
            Assert.IsTrue(result, "ChangeWord should succeed if word exists in word book.");
        }

        [TestMethod]
        public void DeleteWordBook_ShouldReturnTrue_WhenWordBookIsDeletedSuccessfully()
        {
            // Arrange
            string username = "testUser";
            string password = "testPass";
            _dataService.Register(username, password);
            string wordBookTitle = "我的生词本";

            // Act
            bool result = _dataService.DeleteWordBook(username, wordBookTitle);

            // Assert
            Assert.IsTrue(result, "DeleteWordBook should succeed if word book exists.");
        }

        [TestMethod]
        public void RenameWordBook_ShouldReturnTrue_WhenWordBookIsRenamedSuccessfully()
        {
            // Arrange
            string username = "testUser";
            string password = "testPass";
            _dataService.Register(username, password);
            string oldTitle = "我的生词本";
            string newTitle = "新生词本";

            // Act
            bool result = _dataService.RenameWordBook(username, oldTitle, newTitle);

            // Assert
            Assert.IsTrue(result, "RenameWordBook should succeed if word book exists.");
        }
    }
}
